package com.hskn.hss.module.tlcostoperate.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hskn.hss.core.annotation.DataScope;
import com.hskn.hss.core.domain.BaseEntity;
import com.hskn.hss.core.utils.LoginUtils;
import com.hskn.hss.entity.AjaxResult;
import com.hskn.hss.exception.ExcelReaderDataException;
import com.hskn.hss.exception.HssException;
import com.hskn.hss.module.costdictitem.entity.CostDictItem;
import com.hskn.hss.module.costdictitem.mapper.CostDictItemMapper;
import com.hskn.hss.module.costdictitem.service.ICostDictItemService;
import com.hskn.hss.module.depart.entity.SysDepart;
import com.hskn.hss.module.depart.mapper.SysDepartMapper;
import com.hskn.hss.module.tlcostoperate.entity.TlCostOperate;
import com.hskn.hss.module.tlcostoperate.mapper.TlCostOperateMapper;
import com.hskn.hss.module.tlcostoperate.service.ITlCostOperateService;
import com.hskn.hss.module.tlcostoperate.to.CostOperateCfgListTO;
import com.hskn.hss.module.user.entity.User;
import com.hskn.hss.module.user.mapper.UserMapper;
import com.hskn.hss.module.userdepart.entity.SysUserDepart;
import com.hskn.hss.module.userdepart.mapper.SysUserDepartMapper;
import com.hskn.hss.to.ForIdsTO;
import com.hskn.hss.utils.GroupingByUtils;
import com.hskn.hss.utils.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hskn
 * @since 2021-05-20
 */
@Service
public class TlCostOperateServiceImpl extends ServiceImpl<TlCostOperateMapper, TlCostOperate> implements ITlCostOperateService {

    @Resource
    TlCostOperateMapper tlCostOperateMapper;
    @Resource
    SysUserDepartMapper sysUserDepartMapper;
    @Resource
    SysDepartMapper sysDepartMapper;
    @Resource
    UserMapper userMapper;
    @Resource
    CostDictItemMapper costDictItemMapper;
    @Resource
    ICostDictItemService costDictItemService;

    @Override
    public AjaxResult insert(JSONObject params) throws HssException {

        String uid = LoginUtils.getUser().getUid();
        TlCostOperate tlCostOperate = params.getObject("data", TlCostOperate.class);

        QueryWrapper<SysUserDepart> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysUserDepart::getUserid, uid);
        String deptid = sysUserDepartMapper.selectOne(queryWrapper).getDepid();

        tlCostOperate.setCreateby(uid);
        tlCostOperate.setCreatetime(new Date());
        tlCostOperate.setDeptid(deptid);
        int i = tlCostOperateMapper.insert(tlCostOperate);
        boolean flag = i > 0;

        if (flag) {
            return AjaxResult.success("操作成功");
        } else {
            return AjaxResult.fail("操作失败，请稍后再试");
        }
    }

    @Override
    public AjaxResult update(JSONObject params) throws HssException {

        String uid = LoginUtils.getUser().getUid();
        TlCostOperate tlCostOperate = params.getObject("data", TlCostOperate.class);
        tlCostOperate.setUpdateby(uid);
        tlCostOperate.setUpdatetime(new Date());
        int i = tlCostOperateMapper.updateById(tlCostOperate);
        boolean flag = i > 0;
        if (flag) {
            return AjaxResult.success("操作成功");
        } else {
            return AjaxResult.fail("操作失败，请稍后再试");
        }
    }

    @Override
    public AjaxResult deletebyid(ForIdsTO forIdsTO) throws HssException {
        tlCostOperateMapper.deleteBatchIds(forIdsTO.getIds());
        return AjaxResult.success("操作成功");
    }

    @Override
    public TlCostOperate getDetail(JSONObject params) throws HssException {
        String id = params.getString("id");
        TlCostOperate tlCostOperate = tlCostOperateMapper.selectById(id);
        SysDepart depart = sysDepartMapper.selectById(tlCostOperate.getWaterdept());
        User employee = userMapper.selectById(tlCostOperate.getPayperson());
        if (employee != null) {
            tlCostOperate.setPaypersonName(employee.getName());
        }
        if (depart != null) {
            tlCostOperate.setWaterdeptName(depart.getDepartName());
        }
        return tlCostOperate;
    }


    @Override
    @DataScope(deptAlias = "waterdept", userAlias = "createby")
    public JSONObject getList(BaseEntity entity, JSONObject params) throws HssException {
        Long page = StringUtils.isEmpty(params.getLong("page")) ? 1 : params.getLong("page");
        Long size = StringUtils.isEmpty(params.getLong("size")) ? 10 : params.getLong("size");
        JSONObject json = new JSONObject();

        Map<String, Object> map = new HashMap();
        map.put("waterdept", params.getString("waterdept"));
        map.put("starttime", params.getString("starttime"));
        map.put("endtime", params.getString("endtime"));
        map.put("costtype", params.getString("costtype"));
        map.put("costtypeitem", params.getString("costtypeitem"));
        map.put("entity", entity);
        Page<TlCostOperate> listPage = new Page<>(page, size, true);
        IPage<TlCostOperate> iPage = tlCostOperateMapper.listTlCostOperate(listPage, map);
        List<TlCostOperate> list1 = iPage.getRecords();
        List<User> userList = userMapper.selectList(new QueryWrapper<>());
        Map<String, User> userMap = GroupingByUtils.getGroupingForMapEntity(userList, User::getUid, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        Map<String, CostDictItem> costDictItemMap = costDictItemService.getCostDictItemMap(new QueryWrapper<>());
        for (TlCostOperate co : list1) {
            if (userMap.containsKey(co.getPayperson())) {
                co.setPaypersonName(userMap.get(co.getPayperson()).getName());
            }
            if (costDictItemMap.containsKey(co.getCosttypeitem())) {
                co.setCosttypeitemName(costDictItemMap.get(co.getCosttypeitem()).getCostname());
            }
        }
        json.put("total", iPage.getTotal());
        json.put("size", iPage.getSize());
        json.put("pages", iPage.getPages());
        json.put("current", iPage.getCurrent());
        json.put("resultlist", iPage.getRecords());
        return json;
    }

    @Override
    public void excelReader(List<TlCostOperate> costOperateList, String types) throws ExcelReaderDataException {

        String uid = LoginUtils.getUser().getUid();
        List<SysDepart> departList = sysDepartMapper.selectList(new QueryWrapper<>());
        Map<String, SysDepart> departMap = new HashMap<>();
        if (!departList.isEmpty()) {
            Predicate<SysDepart> departNameNotNull = depart -> StringUtils.isNotEmpty(depart.getDepartName());
            departList = departList.stream().filter(departNameNotNull).collect(Collectors.toList());
            departMap = GroupingByUtils.getGroupingForMapEntity(departList, SysDepart::getDepartName, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        }
        List<CostDictItem> costDictItemList = costDictItemMapper.selectList(new QueryWrapper<>());
        Map<String, CostDictItem> costDictItemMap = new HashMap<>();
        if (!costDictItemList.isEmpty()) {
            Predicate<CostDictItem> nameNotNull = costDictItem -> StringUtils.isNotEmpty(costDictItem.getCostname());
            costDictItemList = costDictItemList.stream().filter(nameNotNull).collect(Collectors.toList());
            costDictItemMap = GroupingByUtils.getGroupingForMapEntity(costDictItemList, CostDictItem::getCostname, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        }
        List<User> userList = userMapper.selectList(new QueryWrapper<>());
        Map<String, User> userMap = new HashMap<>();
        if (!userList.isEmpty()) {
            Predicate<User> nameNotNull = user -> StringUtils.isNotEmpty(user.getName());
            userList = userList.stream().filter(nameNotNull).collect(Collectors.toList());
            userMap = GroupingByUtils.getGroupingForMapEntity(userList, User::getName, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        }
        int num = 1;
        String str = "";
        for (TlCostOperate costOperate : costOperateList) {
            costOperate.setCreatetime(new Date());
            costOperate.setCreateby(uid);
            costOperate.setCosttype(types);
            if (StringUtils.isNotEmpty(costOperate.getWaterdeptName())) {
                if (departMap.containsKey(costOperate.getWaterdeptName())) {
                    costOperate.setDeptid(departMap.get(costOperate.getWaterdeptName()).getId());
                    costOperate.setWaterdept(departMap.get(costOperate.getWaterdeptName()).getId());
                } else {
                    str += "第" + num + "条的“‘所属机构’:‘" + costOperate.getWaterdeptName() + "’”" + "不存在;##";
                }
            } else {
                str += "第" + num + "条的“所属机构”不能为空;##";
            }
            if (userMap.containsKey(costOperate.getPaypersonName())) {
                costOperate.setPayperson(userMap.get(costOperate.getPaypersonName()).getUid());
            } else {
                str += "第" + num + "条的“‘缴费人’:‘" + costOperate.getPaypersonName() + "’”" + "不存在;##";
            }
            if (types.equals("杂费")) {
                if (costDictItemMap.containsKey(costOperate.getCosttypeitemName())) {
                    costOperate.setCosttypeitem(costDictItemMap.get(costOperate.getCosttypeitemName()).getId());
                } else {
                    str += "第" + num + "条的“‘费用类型’:‘" + costOperate.getCosttypeitemName() + "’”" + "不存在;##";
                }
            }
            if (Objects.isNull(costOperate.getWaterusage())) {
                str += "第" + num + "条的“用水（电）量”不能为空;##";
            }
            if (Objects.isNull(costOperate.getTotalcost())) {
                str += "第" + num + "条的“总费用”不能为空;##";
            }
            num++;
        }
        if (StringUtils.isNotEmpty(str)) {
            throw new ExcelReaderDataException("您导入的数据:##" + str);
        }
    }

    @Override
    @DataScope(deptAlias = "waterdept", userAlias = "createby")
    public List<TlCostOperate> getTlCostOperate(CostOperateCfgListTO costOperateListTo, SimpleDateFormat format) throws ParseException {
        QueryWrapper<TlCostOperate> costOperateQueryWrapper = new QueryWrapper<>();
        if (costOperateListTo.getParams().containsKey("dataScope") && StringUtils.isNotEmpty(costOperateListTo.getParams().get("dataScope").toString())) {
            costOperateQueryWrapper.lambda().apply(costOperateListTo.getParams().get("dataScope").toString());
        }
        if (com.hskn.hss.core.utils.StringUtils.isNotEmpty(costOperateListTo.getDeptid())) {
            costOperateQueryWrapper.lambda().eq(TlCostOperate::getDeptid, costOperateListTo.getDeptid());
        }
        if (com.hskn.hss.core.utils.StringUtils.isNotEmpty(costOperateListTo.getTypes())) {
            costOperateQueryWrapper.lambda().eq(TlCostOperate::getCosttype, costOperateListTo.getTypes());
        }
        if (com.hskn.hss.core.utils.StringUtils.isNotEmpty(costOperateListTo.getCostType())) {
            costOperateQueryWrapper.lambda().eq(TlCostOperate::getCosttypeitem, costOperateListTo.getCostType());
        }
        if (costOperateListTo.getIds() != null && !costOperateListTo.getIds().isEmpty()) {
            costOperateQueryWrapper.lambda().in(TlCostOperate::getId, costOperateListTo.getIds());
        }
        if (com.hskn.hss.core.utils.StringUtils.isNotEmpty(costOperateListTo.getStartTime()) && com.hskn.hss.core.utils.StringUtils.isNotEmpty(costOperateListTo.getEndTime())) {
            costOperateQueryWrapper.lambda().ge(TlCostOperate::getPaytime, format.parse(costOperateListTo.getStartTime()));
            costOperateQueryWrapper.lambda().le(TlCostOperate::getPaytime, format.parse(costOperateListTo.getEndTime()));
        }
        List<TlCostOperate> costOperateList = tlCostOperateMapper.selectList(costOperateQueryWrapper);
        return costOperateList;
    }
}
